package com.gomoku;

import java.util.*;

public class GameLogic {
    public static final int BOARD_SIZE = 15;
    public static final int[][] DIRECTIONS = {{1, 0}, {0, 1}, {1, 1}, {1, -1}};

    private int[][] board;
    private int currentPlayer;
    private Stack<int[]> moveHistory;
    private boolean gameOver;

    public GameLogic() {
        board = new int[BOARD_SIZE][BOARD_SIZE];
        currentPlayer = 1; // 1 for black, 2 for white
        moveHistory = new Stack<>();
        gameOver = false;
    }

    public int[][] getBoard() {
        return board;
    }

    public int getCurrentPlayer() {
        return currentPlayer;
    }

    public boolean isGameOver() {
        return gameOver;
    }

    public boolean makeMove(int row, int col) {
        if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE ||
                board[row][col] != 0 || gameOver) {
            return false;
        }

        board[row][col] = currentPlayer;
        moveHistory.push(new int[]{row, col});

        if (checkWin(row, col)) {
            gameOver = true;
            return true;
        }

        currentPlayer = currentPlayer == 1 ? 2 : 1;
        return true;
    }

    public void undoMove() {
        if (!moveHistory.isEmpty()) {
            int[] lastMove = moveHistory.pop();
            board[lastMove[0]][lastMove[1]] = 0;
            if (!moveHistory.isEmpty()) {
                currentPlayer = currentPlayer == 1 ? 2 : 1;
            } else {
                currentPlayer = 1;
            }
            gameOver = false;
        }
    }

    public void resetGame() {
        board = new int[BOARD_SIZE][BOARD_SIZE];
        currentPlayer = 1;
        moveHistory = new Stack<>();
        gameOver = false;
    }

    private boolean checkWin(int row, int col) {
        int player = board[row][col];

        for (int[] dir : DIRECTIONS) {
            int count = 1;
            count += countInDirection(row, col, dir[0], dir[1], player);
            count += countInDirection(row, col, -dir[0], -dir[1], player);

            if (count >= 5) {
                return true;
            }
        }

        return false;
    }

    private int countInDirection(int row, int col, int dRow, int dCol, int player) {
        int count = 0;
        int r = row + dRow;
        int c = col + dCol;

        while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE &&
                board[r][c] == player) {
            count++;
            r += dRow;
            c += dCol;
        }

        return count;
    }

    public List<int[]> getMoveHistory() {
        return new ArrayList<>(moveHistory);
    }

    public void loadMoveHistory(List<int[]> history) {
        resetGame();
        for (int[] move : history) {
            makeMove(move[0], move[1]);
        }
    }
}